<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
       html,
       body {
       	margin: 0;
       	height: 100%;
       }
       
       canvas {
       	display: block;
       }
       
       /* 进度条 */
       .progress {
       	position: fixed;
       	width: 100%;
       	height: 100%;
       }
       
       .progress .mask {
       	position: fixed;
       	width: 100%;
       	height: 100%;
       	background: rgba(0, 0, 0, 0.2);
       	z-index: 99;
       }
       
       .progress .loading {
       	width: 30em;
       	height: 1em;
       	background: #fff;
       	position: absolute;
       	left: 50%;
       	top: 50%;
       	transform: translate(-50%, -50%);
       	z-index: 100;
       	border-radius: 1em;
       }
       
       .progress .trends {
       	width: 0;
       	height: 100%;
       	background: red;
       	box-shadow: 1px 1px 10px red;
       	border-radius: 1em;
       	text-align: center;
       	color:#0F0;
       }
       
    </style>
</head>

<body>
	<div id="container"></div>
	<div id="progress" class="progress">
		<div class="mask"></div>
		<div class="loading">
			<div class="trends"></div>
		</div>
	</div>
</body>

	<script src="./js/three.js"></script>
	<script src="./js/loaders/inflate.min.js"></script>
	<script src="./js/loaders/FBXLoader.js"></script>
	<script src="./js/controls/OrbitControls.js"></script>
	<script src="./js/stats.min.js"></script>
	<script src="./js/dat.gui.min.js"></script>

<script>
    var container,renderer, camera, scene, gui, light, stats, controls, meshHelper, mixer, action,datGui;
			 container = document.getElementById('container');
    var clock = new THREE.Clock();
draw();
    function initRender() {
      /*  renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0xeeeeee); */
				
				renderer = new THREE.WebGLRenderer();
				// that.renderer = new THREE.CanvasRenderer();
				
				renderer.setPixelRatio(window.devicePixelRatio);
				// 设置渲染器的初始颜色
				renderer.setClearColor(new THREE.Color(0xeeeeee));
				// 设置输出canvas画面的大小
				renderer.setSize(window.innerWidth, window.innerHeight);
				renderer.shadowMap.enabled = true;
        //告诉渲染器需要阴影效果
        container.appendChild(renderer.domElement);
    }

    function initCamera() {
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000);
       camera.position.set(100, 800, 300);
         // camera.lookAt(new THREE.Vector3(50, 800, 50)); 
				 
				/* camera.position.x = 0;
				 camera.position.y = 15;
				 camera.position.z = 70; */
				 camera.lookAt(scene.position);
    }

    function initScene() {
        scene = new THREE.Scene();
        scene.background = new THREE.Color( 0xa0a0a0 );
			// scene.background = new THREE.Color("#080e30");
				//雾气效果
        // scene.fog = new THREE.Fog( 0xa0a0a0, 500, 1000 );
    }

    //初始化dat.GUI简化试验流程
    function initGui() {
        //声明一个保存需求修改的相关数据的对象
        gui = {
            helper:true ,//模型辅助线
						bgMusic:true,
						volume:50 //初始音量
        };
        datGui = new dat.GUI();
        //将设置属性添加到gui当中，gui.add(对象，属性，最小值，最大值）

        datGui.add(gui, "helper").name('骨骼').onChange(function (e) {
            meshHelper.visible = e;
        })
				datGui.add(gui, "bgMusic").name('背景开启与关闭').onChange(function (e) {
				    // meshHelper.visible = e;
						addMusic() 
				})
				datGui.add( gui, 'volume' ).min(0).max(100).step(1).name('背景音量');
    }

    function initLight() {
        // scene.add(new THREE.AmbientLight(0x444444));

        // light = new THREE.DirectionalLight(0xffffff);
        // light.position.set(0, 300, 100 );

        /* light.castShadow = true;
        light.shadow.camera.top = 180;
        light.shadow.camera.bottom = -100;
        light.shadow.camera.left = -120;
        light.shadow.camera.right = 120; */

        //告诉平行光需要开启阴影投射
        // light.castShadow = true;

        // scene.add(light);
				
				const directionalLight1 = new THREE.DirectionalLight(0xffeeff, 0.8);
				directionalLight1.position.set(1, 1, 1);
			 scene.add(directionalLight1);
				
				const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.8);
				directionalLight2.position.set(-1, 0.5, -1);
				scene.add(directionalLight2);
				
				const ambientLight = new THREE.AmbientLight(0xffffee, 0.25);
				scene.add(ambientLight);
    }

    function initModel() {

        //辅助工具
        var helper = new THREE.AxesHelper(50);
        scene.add(helper);

        // 地板
        var floor = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0xffffff, depthWrite: false } ) );
        floor.rotation.x = - Math.PI / 2;
        floor.receiveShadow = true;
        scene.add( floor );

        //添加地板割线
        var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
        grid.material.opacity = 0.2;
        grid.material.transparent = true;
        scene.add( grid );

        //加载模型
        var loader = new THREE.FBXLoader();
        loader.load("js/models/fbx/fashi_01.fbx", function (mesh) {

            console.log(mesh);
              // mesh.scale.set(50,50,50);
              mesh.position.set(0,0,0);
            //添加骨骼辅助
            meshHelper = new THREE.SkeletonHelper(mesh);
            scene.add(meshHelper);

            //设置模型的每个部位都可以投影
       /*     mesh.traverse( function ( child ) {
                if ( child.isMesh ) {
                    child.castShadow = true;
                    child.receiveShadow = true;
                }
            } ); */

            //AnimationMixer是场景中特定对象的动画播放器。当场景中的多个对象独立动画时，可以为每个对象使用一个AnimationMixer
            mixer = mesh.mixer = new THREE.AnimationMixer(mesh);

            //mixer.clipAction 返回一个可以控制动画的AnimationAction对象  参数需要一个AnimationClip 对象
            //AnimationAction.setDuration 设置一个循环所需要的时间，当前设置了一秒
            //告诉AnimationAction启动该动作
            //action = mixer.clipAction(mesh.animations[0]);
            //action.play();

            var actions = []; //所有的动画数组
            var animations = datGui.addFolder("animations");

            for(var i=0; i<mesh.animations.length; i++){
                createAction(i);
            }

            function createAction(i){
                actions[i] = mixer.clipAction(mesh.animations[i]);
                gui["action"+i] = function () {
                    for(var j=0; j<actions.length; j++){
                        if(j === i){
                            actions[j].play();
														addPositionMusic(mesh,'./source/music/风吹一夏.mp3')
                        }
                        else{
                            actions[j].stop();
                        }
                    }
                };

                animations.add(gui, "action"+i);
            }

            //添加暂停所有动画的按键
            gui.stop = function(){
                for(var i=0; i<actions.length; i++){
                    actions[i].stop();
                }
            };

            datGui.add(gui, "stop");

            // mesh.position.y += 100;
            scene.add(mesh);
        }, onProgress, onError);
    }
		
		//进度通知
		var onProgress = function(xhr) {
			// console.log(xhr)
			if (xhr.lengthComputable) {
		
				var percentComplete = xhr.loaded / xhr.total * 100;
				console.log(Math.round(percentComplete, 2) + '% downloaded');
				play(Math.round(percentComplete, 2))
		
			}
		
			 };
		
		//报错通知
		var onError = function(xhr) {
			console.log("加载错误"+xhr)
		};
		
		function play(a) {
			document.getElementsByClassName("trends")[0].style.width = a + "%";
			document.getElementsByClassName("trends")[0].innerHTML = a + '%';
			if (a < 100) {
				document.getElementById("progress").style.display = "block";
			} else {
				document.getElementById("progress").style.display = "none";
			}
		}
		
    //初始化性能插件
    function initStats() {
        stats = new Stats();
        container.appendChild(stats.dom);
    }

    function initControls() {

        controls = new THREE.OrbitControls(camera, renderer.domElement);
        //设置控制器的中心点
        //controls.target.set( 0, 100, 0 );
        // 如果使用animate方法时，将此函数删除
        //controls.addEventListener( 'change', render );
        // 使动画循环使用时阻尼或自转 意思是否有惯性
        controls.enableDamping = true;
        //动态阻尼系数 就是鼠标拖拽旋转灵敏度
        //controls.dampingFactor = 0.25;
        //是否可以缩放
        controls.enableZoom = true;
        //是否自动旋转
        controls.autoRotate = false;
        controls.autoRotateSpeed = 0.5;
        //设置相机距离原点的最远距离
        controls.minDistance = 1;
        //设置相机距离原点的最远距离
        controls.maxDistance = 2000;
        //是否开启右键拖拽
        controls.enablePan = true;
    }

    function render() {

        var time = clock.getDelta();
        if (mixer) {
            mixer.update(time);
        }

        controls.update();
    }

    //窗口变动触发的函数
    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    function animate() {
        //更新控制器
        render();

        //更新性能插件
        stats.update();

        renderer.render(scene, camera);

        requestAnimationFrame(animate);
    }
//加载背景音乐
function addMusic(){
	// 非位置音频可用于不考虑位置的背景音乐
	// 创建一个监听者
	var listener = new THREE.AudioListener();
	// camera.add( listener );
	// 创建一个非位置音频对象  用来控制播放
	var audio = new THREE.Audio(listener);
	// 创建一个音频加载器对象
	var audioLoader = new THREE.AudioLoader();
	// 加载音频文件，返回一个音频缓冲区对象作为回调函数参数
	audioLoader.load('./source/music/长安城.mp3', function(AudioBuffer) {
	  // console.log(AudioBuffer)
	  // 音频缓冲区对象关联到音频对象audio
	  audio.setBuffer(AudioBuffer);
	  audio.setLoop(true); //是否循环
	  audio.setVolume(.5); //音量
	  // 播放缓冲区中的音频数据
	  audio.play(); //play播放、stop停止、pause暂停
	});

}

//加载位置音乐
function addPositionMusic(posionCube,musicSrc){
	// 用来定位音源的网格模型
/* 	var audioMesh = new THREE.Mesh(new THREE.SphereGeometry(5, 32, 32), new THREE.MeshNormalMaterial());
	// 设置网格模型的位置，相当于设置音源的位置
	audioMesh.position.set(0, 0, 300);
	scene.add(audioMesh); */
/* 	//创建球
	sphere = new THREE.Mesh(new THREE.SphereGeometry(5, 32, 32), material);
	sphere.position.set(-35, -20, 0);
	scene.add(sphere); */
	
	// 创建一个虚拟的监听者
	var listener = new THREE.AudioListener();
	// 监听者绑定到相机对象
	camera.add(listener);
	// 创建一个位置音频对象,监听者作为参数,音频和监听者关联。
	var PosAudio = new THREE.PositionalAudio(listener);
	//音源绑定到一个网格模型上
	posionCube.add(PosAudio);
	// 创建一个音频加载器
	var audioLoader = new THREE.AudioLoader();
	// 加载音频文件，返回一个音频缓冲区对象作为回调函数参数
	audioLoader.load(musicSrc, function(AudioBuffer) {
	  // console.log(buffer);
	  // 音频缓冲区对象关联到音频对象audio
	  PosAudio.setBuffer(AudioBuffer);
	  PosAudio.setVolume(0.9); //音量
	  PosAudio.setRefDistance(200); //参数值越大,声音越大
	  PosAudio.play(); //播放
	});

}

    function draw() {
        //兼容性判断
        // if (!Detector.webgl) Detector.addGetWebGLMessage();

        initGui();
        initRender();
        initScene();
        initCamera();
        initLight();
        initModel();
        initControls();
        initStats();

        animate();
				// addMusic();
        window.onresize = onWindowResize;
    }


</script>
</html>